package Device.printer;

import com.printsdk.cmd.PrintCmd;

import java.text.SimpleDateFormat;
import java.util.Date;

import everbright.uart.library.SerialPortConfig;
import everbright.uart.library.SerialPortHelper;

import static android.os.SystemClock.sleep;

/**
 * Created by everbright6666 on 2020/2/26.
 */

public class printer_control {


    private SerialPortHelper printer_uart;

    private static final String TAG = "PrinterSerialPort";

    public boolean isOpen;


    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm"); // 国际化标志时间格式类
    /*******************************************************************************
     * Function Name  : openSerialPort
     * Description    : 打开相应串口
     * Input          : None
     * Return         : <0时失败，>=0时成功
     *******************************************************************************/
    public int openSerialPort(){

        // 串口参数
        SerialPortConfig serialPortConfig = new SerialPortConfig();
        serialPortConfig.mode = 0;
        serialPortConfig.path = "/dev/ttyS4";
        serialPortConfig.baudRate = 38400;
        serialPortConfig.dataBits = 8;
        serialPortConfig.parity   = 'N';
        serialPortConfig.stopBits = 1;

        if(isOpen) return 0;
        // 初始化串口
        printer_uart = new SerialPortHelper(32);
        // 设置串口参数
        printer_uart.setConfigInfo(serialPortConfig);
        // 开启串口
        isOpen = printer_uart.openDevice();
        if(!isOpen){
            return -1;
        }
        return 1;   //正常返回正值
    }
    /*******************************************************************************
     * Function Name  : closeSerialPort
     * Description    : 关闭相应串口
     * Input          : None
     * Return         : None
     *******************************************************************************/
    public void closeSerialPort() {
        if(isOpen){
            printer_uart.closeDevice();
            isOpen  =   false;
        }
    }

    private void printer_only_sendCommand(byte[] cmd)
    {
        printer_uart.sendCommands(cmd);
        sleep(10);//延时50ms
    }
    private void printer_only_sendCommand(byte[] cmd,int timeout)
    {
        printer_uart.sendCommands(cmd);
        sleep(timeout);
    }

    /**
     * 设置打印浓度2  输入框 【EP802,532ii,G530】
     * @param dessity
     * @return
     */
    private byte[] getPrintDessityII(int dessity) {
        byte[] b_send = new byte[3];
        int iIndex = 0;
        b_send[(iIndex++)] = 0x13;
        b_send[(iIndex++)] = 0x74;
        b_send[(iIndex++)] = 0x44;
        b_send[(iIndex++)] = 0x66;
        b_send[(iIndex++)] = (byte) dessity;
        return b_send;
    }
    /**
     *  退纸
     * @param value 退纸 mm
     * @return byte[]
     */
    private byte[] setPaperBack(int value) {
        byte[] b_send = new byte[3];
        int iIndex = 0;
        b_send[(iIndex++)] = 0x1B;
        b_send[(iIndex++)] = 0x4B;
        b_send[(iIndex++)] =(byte)value ;
        return b_send;
    }
    /**
     * 小字体票据指令 1B 21 01 1C 21 01;掉电无效
     *
     * @return byte[]
     */
    private static byte[] getSamllFontCmd() {
        byte[] bCmd = new byte[6];
        int iIndex = 0;
        bCmd[iIndex++] = 0x1B;
        bCmd[iIndex++] = 0x21;
        bCmd[iIndex++] = 0x01;
        bCmd[iIndex++] = 0x1C;
        bCmd[iIndex++] = 0x21;
        bCmd[iIndex++] = 0x01;
        return bCmd;
    }
    /**
     * 默认大小 1B 21 00 1C 21 00;掉电无效
     *
     * @return byte[]
     */
    private static byte[] getDefaultFontCmd() {
        byte[] bCmd = new byte[6];
        int iIndex = 0;
        bCmd[iIndex++] = 0x1B;
        bCmd[iIndex++] = 0x21;
        bCmd[iIndex++] = 0x00;
        bCmd[iIndex++] = 0x1C;
        bCmd[iIndex++] = 0x21;
        bCmd[iIndex++] = 0x00;
        return bCmd;
    }
    /**
     * 补偿值:所有打印效果项
     * 1D 28 41 02 00 00 04  掉电保存有效
     * @return byte[]
     */
    public static byte[] getAllCompensateCmd() {
        byte[] bCmd = new byte[7];
        int iIndex = 0;
        bCmd[iIndex++] = 0x1D;
        bCmd[iIndex++] = 0x28;
        bCmd[iIndex++] = 0x41;
        bCmd[iIndex++] = 0x02;
        bCmd[iIndex++] = 0x00;
        bCmd[iIndex++] = 0x00;
        bCmd[iIndex++] = 0x04;
        return bCmd;
    }
    /**
     * 设置有效补偿值
     * 1D 43 n 掉电保存有效
     * @return byte[]
     */
    public static byte[] getCompensateCmd(int compensate) {
        byte[] bCmd = new byte[3];
        int iIndex = 0;
        bCmd[iIndex++] = 0x1D;
        bCmd[iIndex++] = 0x43;
        bCmd[iIndex++] = (byte)compensate;
        return bCmd;
    }

    /**
     * 3.18-02 设定下划线  【MS-D245对字符有效1C 21 08】
     * @param underline 0  无， 1 一个点下划线，2 两个点下划线 ；其他无效
     *      描述：设置下划线（字符，ASCII 都有效）
     */
    private static byte[] SetUnderline2(int underline) {
        byte[] bCmd = new byte[3];
        int iIndex = 0;
        bCmd[iIndex++] = 0x1C;
        bCmd[iIndex++] = 0x21;
        if (underline == 1)
            bCmd[iIndex++] = 0x08;
        else
            bCmd[iIndex++] = 0x0;
        return bCmd;
    }
    // 设置MIP6 黑标检测的AD界限值
    private static byte[] setMarkADLimitValue(int adLimitValue) {
        byte[] bCmd = new byte[6];
        int iIndex = 0;
        bCmd[iIndex++] = 0x13;
        bCmd[iIndex++] = 0x74;
        bCmd[iIndex++] = 0x11;
        bCmd[iIndex++] = 0x66;
        if (adLimitValue < 32) {
            adLimitValue = 32;
        }
        if (adLimitValue > 128) {
            adLimitValue = 128;
        }
        bCmd[iIndex++] = (byte) adLimitValue;
        return bCmd;
    }
    // 开启黑标  MS-G530,MS-532IIs,EP802，TS101
    private byte[] openBlackMark(int bmType) {
        byte[] b_send = new byte[5];
        int iIndex = 0;
        b_send[(iIndex++)] = 0x13;
        b_send[(iIndex++)] = 0x74;
        b_send[(iIndex++)] = 0x44;
        b_send[(iIndex++)] = 0x33;
        if(bmType == 0)
            b_send[(iIndex++)] = 0x33;
        else
            b_send[(iIndex++)] = (byte) 0xCC;
        return b_send;
    }
    //获取打印机状态
    public int GetStatus()
    {

        printer_uart.sendCommands(PrintCmd.GetStatus());
        byte[] all_receive_buf =  printer_uart.receiveCommands(32,150);
        if (all_receive_buf != null)
        {
            int ret = PrintCmd.CheckStatus(all_receive_buf);
            return ret;
        }
        return -1;
    }
    //设置国家和区域代码（例:7  西班牙  + 15 PC1252,具体参考文档）
    public void setCodePage(int type,int codepage){
        //清缓存
        printer_uart.sendCommands(PrintCmd.SetClean(),0);
        if(type==0){
            printer_uart.sendCommands(printerUtils.getAscllCmd(codepage));//// ASCLL码(区域国家)
        }else{
            printer_uart.sendCommands(printerUtils.getCodePageCmd(codepage));   //代码页设置
        }
    }
    // 黑标切纸：打印并走纸到下页首，清理缓存
    public void PrintMarkFeedCutpaper(int cutter) {
        try {
            printer_only_sendCommand(PrintCmd.PrintMarkpositioncut());     //黑标功能有效时走纸到预设黑标切纸位置
            printer_only_sendCommand(PrintCmd.PrintCutpaper(cutter));       //打印切纸:全切
            printer_only_sendCommand(PrintCmd.SetClean());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 清理缓存，缺省模式
    public void CleanPrinter() {
        printer_uart.sendCommands(PrintCmd.SetClean());
    }
    // 打印pdf417二维码
    private void printPdf417Code(){
        printer_uart.sendCommands(PrintCmd.SetClean());
        printer_uart.sendCommands(PrintCmd.SetLeftmargin(50));
        printer_uart.sendCommands(PrintCmd.setPdf417(2, 40));
        printer_uart.sendCommands(PrintCmd.PrintPdf417(12, 4, "1234567890abcdefghijklmnopqrst"));
        printer_uart.sendCommands(PrintCmd.PrintFeedline(6));

        printer_uart.sendCommands(PrintCmd.SetLeftmargin(30));
        printer_uart.sendCommands(PrintCmd.setPdf417(3, 60));
        printer_uart.sendCommands(PrintCmd.PrintPdf417(12, 4, "1234567890abcdefghijklmnopqrst"));
        printer_uart.sendCommands(PrintCmd.PrintFeedline(6));

        printer_uart.sendCommands(PrintCmd.SetLeftmargin(30));
        printer_uart.sendCommands(PrintCmd.setPdf417(4, 100));
        printer_uart.sendCommands(PrintCmd.PrintPdf417(12, 4, "1234567890abcdefghijklmnopqrst"));
        printer_uart.sendCommands(PrintCmd.PrintFeedline(6));

    }
    // 打印二维码
    public void printQRCode(String qrcode) {
        // 2018-08-13测试结果：MS-D347(VE14-08-25-A3 LC3N) 参数要求：左边界不超过30,size(1-3),模式：0
        printer_uart.sendCommands(PrintCmd.PrintQrcode(qrcode, 20, 3, 0));
        printer_uart.sendCommands(PrintCmd.PrintFeedline(2));

    }
    //设置黑标打印进纸偏移量,电影票设置为560
    public void setMarkoffsetValue(int markoffsetValue){

        if(markoffsetValue >= 0 || markoffsetValue <= 1600){
            printer_uart.sendCommands(PrintCmd.SetMarkoffsetprint(markoffsetValue));
        }
    }
    // 设置打印浓度 （默认：80,浓度范围：70-200）
    public int setPrintDessity(int densityValue) {

        if (densityValue >= 70 && densityValue <= 200) {
            printer_uart.sendCommands(getPrintDessityII(densityValue));
            return 0;
        } else {
            printer_uart.sendCommands(getPrintDessityII(100));
            return -1;  // "超出输入范围！范围为：70-200"
        }
    }
    // 打印所有补偿值效果
    public void compensatePrintBy(boolean flag,int type){
        if(!flag){
            printer_uart.sendCommands(getAllCompensateCmd());
            //打印所有补偿值效果成功！
            printer_uart.sendCommands(PrintCmd.PrintCutpaper(0));
        }else{
            printer_uart.sendCommands(getCompensateCmd(type));
            //"补偿值设置：" + String.valueOf(type))
            printer_uart.sendCommands(PrintCmd.PrintCutpaper(0));
        }
    }



    //打印测试页
    public int PrintTestPage() {

        printer_uart.sendCommands(openBlackMark(0));       //开启黑标
        //printer_uart.sendCommands(openBlackMark(1));              //关闭黑标
        printer_uart.sendCommands(PrintCmd.PrintMarkpositionprint());  // 检测黑标进纸到打印位置
//			CleanPrinter(); // 清理缓存，缺省模式
        printer_uart.sendCommands(PrintCmd.SetAlignment(1));
        printer_uart.sendCommands(PrintCmd.SetSizetext(1, 1));
        printer_uart.sendCommands(PrintCmd.PrintString( printerConstant.TITLE_CN, 0));

        // 小票号码
        printer_uart.sendCommands(PrintCmd.SetBold(1));
        printer_uart.sendCommands(PrintCmd.SetSizetext(1, 1));
        printer_uart.sendCommands(PrintCmd.SetAlignment(1));
        printer_uart.sendCommands(PrintCmd.PrintString("123456789\n\n", 0));
        printer_uart.sendCommands(PrintCmd.SetBold(0));
        printer_uart.sendCommands(PrintCmd.SetSizetext(0, 0));
        printer_uart.sendCommands(PrintCmd.SetAlignment(0));
        // 小票主要内容
        printer_uart.sendCommands(PrintCmd.PrintString(printerConstant.STRDATA_CN, 0));
        // 二维码
        printer_uart.sendCommands(PrintCmd.PrintFeedline(2));
//		    printQRCode();  // 二维码打印
        printer_uart.sendCommands(PrintCmd.PrintQrcode(printerConstant.WebAddress, 4, 6, 0));
        printer_uart.sendCommands(PrintCmd.PrintFeedline(3));
        // 日期时间
        printer_uart.sendCommands(PrintCmd.SetAlignment(2));//右对齐
        printer_uart.sendCommands(PrintCmd.PrintString(sdf.format(new Date()).toString() + "\n\n", 1));
        printer_uart.sendCommands(PrintCmd.SetAlignment(0));//左对齐
        // 一维条码
        printer_uart.sendCommands(PrintCmd.SetAlignment(1));//居中
//			ComA.send(PrintCmd.Set1DBarCodeAlign(1));
        printer_uart.sendCommands(PrintCmd.Print1Dbar(2, 100, 0, 2, 10, "0123456"));       //  CODE128   6
        printer_uart.sendCommands(PrintCmd.SetAlignment(0));

//			ComA.send(PrintCmd.Set1DBarCodeAlign(0));
//			ComA.send(PrintCmd.Print1Dbar(2, 100, 0, 2, 10, "01234567891"));   //  CODE128   11
//			ComA.send(PrintCmd.Print1Dbar(2, 100, 0, 2, 4, "012345678"));      //  CODE39    9
//			ComA.send(PrintCmd.Print1Dbar(2, 100, 0, 2, 9, "012345678"));      //  CODE93    9
        printer_uart.sendCommands(PrintCmd.PrintMarkpositioncut());     //黑标功能有效时走纸到预设黑标切纸位置
        printer_uart.sendCommands(PrintCmd.PrintCutpaper(0));       //打印切纸:全切

        return 1;

    }

    public void PrintMovieTicket() {

     //   printer_uart.sendCommands(openBlackMark(0));          //开启黑标
//       printer_uart.sendCommands(PrintCmd.SetMarkoffsetcut(572));    //开机时，只需要设置一次即可
//        printer_uart.sendCommands(PrintCmd.SetMarkoffsetprint(572));    //

        printer_only_sendCommand(PrintCmd.SetSizechinese(0,0,0,1));        //设置汉字放大:无倍高，无倍宽，无下划线,字体16*16
        //printer_only_sendCommand(PrintCmd.SetSizechinese(0,0,0,0));        //设置汉字放大:无倍高，无倍宽，无下划线,字体24*24
        printer_only_sendCommand(PrintCmd.SetSizechar(0,0,0,1));           //设置ASCII放大:无倍高，无倍宽，无下划线,字体12*24
        printer_only_sendCommand(PrintCmd.SetLinespace(10));                                //设置行间距:10, 单位0.125mm
        printer_only_sendCommand(PrintCmd.SetAlignment(0));        //左对齐
        //printer_only_sendCommand(PrintCmd.SetSizetext(0, 0));
        //执行到影厅位置
        printer_only_sendCommand(PrintCmd.PrintString("\n\n\n\n\n\n\n", 1));

        //使用水平制表来打印影厅、时间、和副券影厅
        byte[] h_position = new byte[3];
        h_position[0] = 4;
        h_position[1] = 28;
        h_position[2] = 50;
        printer_only_sendCommand(PrintCmd.SetHTseat(h_position,3));
        //影厅
        printer_only_sendCommand(PrintCmd.PrintNextHT());
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_HALL_CN, 1));
        // 日期时间
        printer_only_sendCommand(PrintCmd.PrintNextHT());
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_PLAY_DATE+" "+printerConstant.MOVIE_PLAY_TIME, 1));
        //副券影厅
        printer_only_sendCommand(PrintCmd.PrintNextHT());
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_HALL_CN+"\n\n\n\n", 1));
        //影片名
        printer_only_sendCommand(PrintCmd.SetSizechinese(0,0,0,0));    //大点的字体
        printer_only_sendCommand(PrintCmd.SetSizechar(0,0,0,0));
        printer_only_sendCommand(PrintCmd.SetHTseat(h_position,1));
        printer_only_sendCommand(PrintCmd.PrintNextHT());
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_NAME+"\n\n", 1));


        printer_only_sendCommand(PrintCmd.SetSizechinese(0,0,0,1));    //小点的字体
        printer_only_sendCommand(PrintCmd.SetSizechar(0,0,0,1));
        //副券观影日期
        printer_only_sendCommand(PrintCmd.SetAlignment(2));        //右对齐
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_PLAY_DATE+"    \n", 1));
        //票号
        printer_only_sendCommand(PrintCmd.SetAlignment(0));        //左对齐
        h_position[1] = 30;
        h_position[2] = 53;
        printer_only_sendCommand(PrintCmd.SetHTseat(h_position,3));
        printer_only_sendCommand(PrintCmd.PrintNextHT());
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_CUSTOMER_SEAT, 1)); //座位
        printer_only_sendCommand(PrintCmd.PrintNextHT());
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_SEE_FEE, 1));       //观影费
        //副券时间
        printer_only_sendCommand(PrintCmd.PrintNextHT());
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_PLAY_TIME+"\n\n\n", 1));
        //票类
        printer_only_sendCommand(PrintCmd.SetAlignment(0));        //左对齐
        printer_only_sendCommand(PrintCmd.SetHTseat(h_position,1));
        printer_only_sendCommand(PrintCmd.PrintNextHT());
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_TICKET_TYPE+"\n\n\n", 1));
        //售票时间
        printer_only_sendCommand(PrintCmd.SetHTseat(h_position,2));
        printer_only_sendCommand(PrintCmd.PrintNextHT());
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_TICKET_SELL_DATETIME, 1));
        //工号
        printer_only_sendCommand(PrintCmd.PrintNextHT());
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_SELLER_NO+"\n", 1));
        //副券座号
        printer_only_sendCommand(PrintCmd.SetAlignment(2));        //右对齐
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_CUSTOMER_SEAT+"  \n\n\n\n\n", 1));
        //详情
        printer_only_sendCommand(PrintCmd.SetAlignment(0));        //左对齐
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_INTRODUCE+"\n\n\n", 1));
        //副券票号
        printer_only_sendCommand(PrintCmd.SetAlignment(2));        //右对齐
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_TICKET_NO+"\n\n\n\n\n\n\n\n", 1));
        //副券票价
        printer_only_sendCommand(PrintCmd.PrintString(printerConstant.MOVIE_SEE_FEE+"  \n", 1));
        PrintMarkFeedCutpaper(0);//黑标功能有效时走纸到预设黑标切纸位置,全切
    }

}
